package com.icode.dao.impl;

import com.icode.core.dto.house.EquipmentDTO;
import com.icode.core.dto.house.HouseBaseDTO;
import com.icode.core.dto.house.HouseInfoDTO;
import com.icode.core.dto.house.HouseParamDTO;
import com.icode.core.dto.order.PageDTO;
import com.icode.core.model.house.*;
import com.icode.core.shared.StringUtils;
import com.icode.dao.HouseDao;
import org.hibernate.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: SunKai
 * Date: 14-10-30
 * Time: 下午11:31
 * To change this template use File | Settings | File Templates.
 */
@Repository("houseDao")
public class HouseDaoImpl extends EntityDaoImpl implements HouseDao {
    @Override
    public List<Equipment> findEquipmentsByType(EquipmentType type) {
        String hql = "from " + Equipment.class.getName() + " e where e.type=:type and e.active=:isActive";
        Query query = currentSession().createQuery(hql);
        query.setParameter("type", type);
        query.setParameter("isActive", true);
        return query.list();
    }

    @Override
    public void saveOrUpdateEquipmentByGuid(EquipmentDTO equipmentDTO) {
        String hql = "update " + Equipment.class.getName() + " e set e.name=:name where e.guid=:guid";
        Query query = currentSession().createQuery(hql);
        query.setParameter("name", equipmentDTO.getName());
        query.setParameter("guid", equipmentDTO.getGuid());
        query.executeUpdate();
    }

    @Override
    @Transactional
    public void saveOrUpdateHouseBase(HouseBase houseBase) {
        currentSession().save(houseBase);
    }

    @Override
    public void saveOrUpdateHouseBaseByGuid(HouseBase houseBase, String guid) {
        HouseBase find = findByGuid(HouseBase.class, guid);
        find.initHouseBase(houseBase.title(), houseBase.introduction(), houseBase.information(), houseBase.price(), houseBase.productType(), houseBase.houseBaseArea(), houseBase.themes(), houseBase.fineTheme());
        if (houseBase.houseBaseImages() != null) {
            find.initImages(houseBase.houseBaseImages());
        }
    }

    @Override
    public List<HouseBase> findHouseBase(String currentPage) {
        String hql = "from " + HouseBase.class.getName() + " a where 0=0 order by a.sort";
        Query query = currentSession().createQuery(hql);
        query.setFirstResult((Integer.parseInt(currentPage) - 1) * PageDTO.pageOfData);
        query.setMaxResults(PageDTO.pageOfData);
        List<HouseBase> houseBases = query.list();
        return houseBases;
    }

    @Override
    public Object findTotalPage(Class clazz) {
        String hql = "select ceil(count(*)/:pageOfData) from " + clazz.getName();
        Query query = currentSession().createQuery(hql);
        query.setParameter("pageOfData", (long) PageDTO.pageOfData);
        return query.uniqueResult();
    }

    @Override
    public void deleteHouseBase(HouseBase houseBase) {
        currentSession().delete(houseBase);
    }


    @Override
    public void deleteHouseBaseImage(HouseBase houseBase) {
        deleteUploadImage(houseBase);
        String hql = "delete from " + HouseBaseImage.class.getName() + " a where a.houseBase = :houseBase";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseBase", houseBase);
        query.executeUpdate();
    }

    private void deleteUploadImage(HouseBase houseBase) {
        String getId = "select a.houseBaseImages from " + HouseBaseImage.class.getName() + " a where a.houseBase=:houseBase";
        Query query = currentSession().createQuery(getId);
        query.setParameter("houseBase", houseBase);
        List<UploadImage> imageId = query.list();
        String hql = "delete from " + UploadImage.class.getName() + " a where a.id = :id";
        Query query2 = currentSession().createQuery(hql);
        for (UploadImage h : imageId) {
            query2.setParameter("id", Integer.parseInt(h.id()));
            query2.executeUpdate();
        }
    }

    @Override
    public void deleteUploadImageByGuid(String guid) {
        String getId = "from " + UploadImage.class.getName() + " a where a.guid=:guid";
        Query query = currentSession().createQuery(getId);
        query.setParameter("guid", guid);
        List<UploadImage> image = query.list();
        String delImg = "delete from " + UploadImage.class.getName() + " a where a.id=:id";
        Query query1 = currentSession().createQuery(delImg);
        query1.setParameter("id", Integer.parseInt(image.get(0).id()));
        query1.executeUpdate();
        String hql = "delete from " + HouseBaseImage.class.getName() + " a where a.houseBaseImages = :houseBaseImages";
        Query query2 = currentSession().createQuery(hql);
        query2.setParameter("houseBaseImages", image.get(0));
        query2.executeUpdate();
    }

    @Override
    public List<BuildingType> findBuildingTypeByHouseBase(HouseBase houseBase) {
        String hql = "from " + BuildingType.class.getName() + " a where a.houseBase=:houseBase";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseBase", houseBase);
        List<BuildingType> buildingTypes = query.list();
        return buildingTypes;
    }

    @Override
    public List<HouseBase> findHouseBaseByTitle(String title) {
        String hql = "from " + HouseBase.class.getName() + " a where a.title=:title";
        Query query = currentSession().createQuery(hql);
        query.setParameter("title", title);
        List<HouseBase> houseBases = query.list();
        return houseBases;
    }

    @Override
    public List<HouseBase> findAllApartment() {
        String hql = "from " + HouseBase.class.getName() + " a where a.productType=:productType";
        Query query = currentSession().createQuery(hql);
        query.setParameter("productType", ProductType.APARTMENT);
        return query.list();
    }

    @Override
    @Transactional
    public List<HouseBase> findAllHouseBase(ProductType productType) {
        String hql = "from " + HouseBase.class.getName() + " a where a.productType=:productType order by a.sort";
        Query query = currentSession().createQuery(hql);
        query.setParameter("productType", productType);
        return query.list();
    }

    @Override
    public List<HouseInfo> findHouseInfoByBuildingType(String buildingTypeGuid) {
        String hql = "from " + HouseInfo.class.getName() + " a where a.buildingType.guid=:buildingTypeGuid";
        Query query = currentSession().createQuery(hql);
        query.setParameter("buildingTypeGuid", buildingTypeGuid);
        return query.list();
    }

    @Override
    public List<HouseBaseImage> findHouseBaseImageByHouseBaseId(String houseBaseId) {
        HouseBase houseBase = (HouseBase) currentSession().get(HouseBase.class, Integer.parseInt(houseBaseId));
        String hql = "from " + HouseBaseImage.class.getName() + " a where a.houseBase=:houseBase";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseBase", houseBase);
        return query.list();
    }

    @Override
    public List<HouseBase> findHouseBaseByMoreCondition(String area, String price, String productType, String theme) {
        String hql = "from " + HouseBase.class.getName() + " a where 0=0 " + area + price + theme + productType;
        Query query = currentSession().createQuery(hql);
        return query.list();
    }


    @Override
    public BuildingType findBuildingTypeByGuid(String buildingGuid) {
        String hql = "from " + BuildingType.class.getName() + " a where a.guid=:guid";
        Query query = currentSession().createQuery(hql);
        query.setParameter("guid", buildingGuid);
        List<BuildingType> list = query.list();
        return list.isEmpty() ? null : list.get(0);
    }

    @Override
    public void deleteBuildingTypeImageByGuid(UploadImage uploadImage) {
        String hql = "delete from " + BuildingTypeImage.class.getName() + " a where a.image=:image";
        Query query = currentSession().createQuery(hql);
        query.setParameter("image", uploadImage);
        query.executeUpdate();
    }

    @Override
    public void deleteObject(Object object) {
        currentSession().delete(object);
    }

    @Override
    public List<HouseBaseDTO> loadByParam(HouseParamDTO houseParamDTO) {
        return null;
    }

    @Override
    public List<HouseBase> findHouseByProductType(String productType) {
        String hql = "from " + HouseBase.class.getName() + " a where 0=0 " + productType;
        Query query = currentSession().createQuery(hql);
        return query.list();
    }

    public List<FirstBanners> findFirstBanners(UploadImage image) {
        String hql = "from " + FirstBanners.class.getName() + " h where h.image =:image";
        Query query = currentSession().createQuery(hql);
        query.setParameter("image", image);
        return query.list();
    }

    @Override
    public BannerForApp findSecondBannerByImage(String imgGuid) {
        String hql = "from " + BannerForApp.class.getName() + " t where t.secondBanner.guid=:guid";
        Query query = currentSession().createQuery(hql);
        query.setParameter("guid", imgGuid);
        List list = query.list();
        return list.isEmpty() ? null : (BannerForApp) list.get(0);
    }

    @Override
    @Transactional
    public void deleteAgreementByHouseInfo(HouseInfo houseInfo) {
        String hql = "delete from " + Agreement.class.getName() + " a where a.houseInfo=:houseInfo";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseInfo", houseInfo);
        query.executeUpdate();
    }

    @Override
    @Transactional
    public Agreement findAgreementByHouseInfo(HouseInfo houseInfo) {
        String hql = "from " + Agreement.class.getName() + " a where a.houseInfo=:houseInfo";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseInfo", houseInfo);
        List list = query.list();
        return list.isEmpty() ? null : (Agreement) list.get(0);
    }

    @Override
    @Transactional
    public Object findTotalPageByStatus(Class clazz, String status) {
        String hql = "select ceil(count(*)/:pageOfData) from " + clazz.getName() + " a where a.myHouseStatus=:status";
        Query query = currentSession().createQuery(hql);
        if (clazz.getName().endsWith("Rent")) {
            switch (status) {
                case "TORENT":
                    query.setParameter("status", MyHouseStatus.TORENT);
                    break;
                case "RENTING":
                    query.setParameter("status", MyHouseStatus.RENTING);
                    break;
                case "RENTED":
                    query.setParameter("status", MyHouseStatus.RENTED);
                    break;
            }
        }
        if (clazz.getName().endsWith("Assignment")) {
            switch (status) {
                case "TOASSIGNMNET":
                    query.setParameter("status", MyHouseStatus.TOASSIGNMNET);
                    break;
                case "ASSIGNMENTED":
                    query.setParameter("status", MyHouseStatus.ASSIGNMENTED);
                    break;
            }
        }
        query.setParameter("pageOfData", (long) PageDTO.pageOfData);
        return query.uniqueResult();
    }

    @Override
    @Transactional
    public void deleteUploadImageByGuidForHouseInfo(String imgGuid) {
        String getId = "from " + UploadImage.class.getName() + " a where a.guid=:guid";
        Query query = currentSession().createQuery(getId);
        query.setParameter("guid", imgGuid);
        List<UploadImage> image = query.list();
        String delImg = "delete from " + UploadImage.class.getName() + " a where a.id=:id";
        Query query1 = currentSession().createQuery(delImg);
        query1.setParameter("id", Integer.parseInt(image.get(0).id()));
        query1.executeUpdate();
        String hql = "delete from " + HouseInfoImage.class.getName() + " a where a.image = :HouseInfoImage";
        Query query2 = currentSession().createQuery(hql);
        query2.setParameter("HouseInfoImage", image.get(0));
        query2.executeUpdate();
    }

    @Override
    @Transactional
    public void deleteUploadHouseExtraFeeByGuid(String guid) {
        String getId = "from " + HouseExtraFee.class.getName() + " a where a.guid=:guid";
        Query query = currentSession().createQuery(getId);
        query.setParameter("guid", guid);
        List<HouseExtraFee> houseExtraFees = query.list();
        String delhouseExtraFees = "delete from " + HouseExtraFee.class.getName() + " a where a.id=:id";
        Query query1 = currentSession().createQuery(delhouseExtraFees);
        query1.setParameter("id", Integer.parseInt(houseExtraFees.get(0).id()));
        query1.executeUpdate();
    }

    @Override
    @Transactional
    public List<HouseInfo> findhouseInfoByhouseBaseArea(String houseBaseArea) {
        String hql = "from " + HouseInfo.class.getName() + " a where a.buildingType.houseBase.houseBaseArea=:houseBaseArea";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseBaseArea", HouseBaseArea.valueOf(houseBaseArea));
        return query.list();
    }

    @Override
    @Transactional
    public void deleteByLogic(boolean isActive, String guid) {
        String hql = "update " + Equipment.class.getName() + " a set a.active=:isActive where a.guid=:guid";
        Query query = currentSession().createQuery(hql);
        query.setParameter("isActive", isActive);
        query.setParameter("guid", guid);
        query.executeUpdate();
    }

    @Override
    @Transactional
    public void deleteHouserhouseInfoImages(HouseInfo houseInfoFound) {
        String hql = "delete from " + HouseInfoImage.class.getName() + " a where a.houseInfo =:houseInfo";
        Query query = currentSession().createQuery(hql);
        query.setParameter("houseInfo",houseInfoFound);
        query.executeUpdate();
    }
}
